﻿#ifndef ConstantBuffer_h
#define ConstantBuffer_h

#include <Defines.h>
#include <CSharpPropertyMethods.h>

// Riccsson includes.
#include <System/Object.h>
#include <System/Array.h>
#include <System/String.h>

// XNA includes.
#include "../GraphicsDevice.h"
#include "ShaderStage.h"
#include "../Effect/EffectParameter.h"
#include "../Effect/EffectParameterCollection.h"

namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			namespace Graphics
			{
				/*internal*/ class ConstantBuffer
					: GraphicsResource
				{
					private: /*readonly*/ GC_PTR<Riccsson::System::Array<byte>> _buffer;

					private: /*readonly*/ GC_PTR<Riccsson::System::Array<int>> _parameters;

					private: /*readonly*/ GC_PTR<Riccsson::System::Array<int>> _offsets;

					private: /*readonly*/ GC_PTR<Riccsson::System::string> _name;

					private: ulong _stateKey;

					private: bool _dirty;

			#if DIRECTX

					private: SharpDX.Direct3D11.Buffer _cbuffer;

			#elif OPENGL

					private: int _program = -1;
					private: int _location;

					static GC_PTR<ConstantBuffer> _lastConstantBufferApplied = null;

					/// <summary>
					/// A hash value which can be used to compare constant buffers.
					/// </summary>
					public: /*internal*/ int HashKey { get; private: set; }

			#endif

					public: ConstantBuffer(GC_PTR<ConstantBuffer> cloneSource)
					{
						throw;
					}

					public: ConstantBuffer(GC_PTR<GraphicsDevice> device,
										  int sizeInBytes,
										  Riccsson::System::Array<int>* parameterIndexes,
										  Riccsson::System::Array<int>* parameterOffsets,
										  GC_PTR<Riccsson::System::String> name)
					{
						throw;
					}

					private: void Initialize()
					{
						throw;
					}

					public: /*internal*/ void Clear()
					{
			#if OPENGL
						// Force the uniform location to be looked up again
						_program = -1;
			#endif
					}

					private: void SetData(int offset, int rows, int columns, Riccsson::System::object* data)
					{
						throw;
					}

					private: int SetParameter(int offset, EffectParameter* param)
					{
						throw;
					}

					public: void Update(EffectParameterCollection* parameters)
					{
						throw;
					}

			#if DIRECTX

					public: /*internal*/ void Apply(GC_PTR<GraphicsDevice> device, ShaderStage stage, int slot)
					{
						throw;
					}

			#elif OPENGL || PSM

					public: unsafe void Apply(GraphicsDevice device, int program)
					{
						throw;
					}

			#endif

				};
			}
		}
	}
}

#endif